package cn.blnp.net.flowable.boot.utils;

import cn.blnp.net.flowable.boot.annotations.TenantAnnotation;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * <h3>多租户流程助手</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/6/10 10:50
 */
@Slf4j
@Component
public class MultiTenantDeployUtil {

    /**
     * <p><b>用途:指定租户部署流程<b></p>
     * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
     * @since 10:53 2025/6/10
     * @params [repositoryService, tenantId, key, resource]
     * @param repositoryService
     * @param tenantId
     * @param key
     * @param resource
     * @return org.flowable.engine.repository.ProcessDefinition
    **/
    @TenantAnnotation(tenantId = "#tenantId")
    public ProcessDefinition deployByTenant(RepositoryService repositoryService, String tenantId, String key, String resource) {
        //部署流程
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource(resource).key(key).tenantId(tenantId).deploy();
        //查询流程定义
        ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        log.info("version:{},id:{}, key:{},tenantId:{}", procDef.getVersion(),
                procDef.getId(), procDef.getKey(), procDef.getTenantId());
        return procDef;
    }

    /**
     * <p><b>用途:根据租户查询流程定义信息<b></p>
     * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
     * @since 10:54 2025/6/10
     * @params [repositoryService, tenantId, key]
     * @param repositoryService
     * @param tenantId
     * @param key
     * @return java.util.List<org.flowable.engine.repository.ProcessDefinition>
    **/
    @TenantAnnotation(tenantId = "#tenantId")
    public List<ProcessDefinition> queryProcessDefinitionFromTenant(RepositoryService repositoryService, String tenantId, String key) {
        List<ProcessDefinition> processDefList = repositoryService.createProcessDefinitionQuery()
                .processDefinitionTenantId(tenantId)
                .processDefinitionKey(key)
                .list();
        SimplePropertyPreFilter processDefFilter =
                new SimplePropertyPreFilter(ProcessDefinition.class,
                        "version", "id", "key", "tenantId");
        log.info("业务方{}下的流程定义有:{}",
                tenantId, JSON.toJSONString(processDefList, processDefFilter));
        return processDefList;
    }
}
